﻿<h1>Syntax/Semantics Exceptions in Go</h1>

<p>
This article will list all kinds of syntax/semantics exceptions in Go.
Some of these exceptions are syntactic sugars to make programming convenient,
some are caused built-in generic privileges,
some exists for history reasons, and some exists for other reasons in logic.
</p>

<a class="anchor" id="nest-function-calls"></a>
<h3>Nested function calls</h3>

<div>
The basic rule:
<div class="alert alert-info">
If the number of the return results of a function call is not zero,
and the return results can be used as the whole arguments of another function call,
then the former function call can be nested in the latter function call,
the former nested call can't mix up with other arguments of the latter nesting call.
</div>

Sugar:
<div class="alert alert-success">
If a function call returns exactly one result,
then the function call can be always be used as a single-value argument in other function calls,
the single-result function call can mix up with other arguments of the nesting function calls.
</div>

Exception:
<div class="alert alert-success">
For the standard Go compiler (but not for gccgo),
the basic rule doesn't apply to nesting calls to built-in <code>print</code> and <code>println</code> functions.
Calls to these functions can't nest multi-result function calls as arguments.
</div>

<!--
Exception:
<div class="alert alert-success">
For the standard Go compiler,
the basic rule doesn't apply to nesting calls of some built-in functions with multiple input parameters,
including <code>copy</code>, <code>delete</code>, <code>print</code> and <code>println</code> functions.
Calls to these functions can't nest multi-result function calls as arguments.
</div>

<p><i>
(Since Go 1.13, the exception <a href="https://github.com/golang/go/issues/15992">will become invalid</a>
for the <code>copy</code> and <code>delete</code> built-in functions,
but it will <a href="https://github.com/golang/go/issues/20656">continue being valid</a>
for the <code>print</code> and <code>println</code> built-in functions.)
</i></p>

<p><i>
(For the standard Go compiler,
the basic rule applies to the nesting calls of <code>complex</code> function,
but with <a href="https://github.com/golang/go/issues/15992#issuecomment-337673303">one exception case</a>
when a method call with an interface receiver argument as the only argument of the nesting calls.
This exception case may be a bug of the standard Go compiler. The bug will be fixed in Go SDK 1.13.)
</i></p>
-->

Example:
<pre class="line-numbers"><code class="language-go">package main

import (
	"fmt"
)

func f0() float64 {return 1}
func f1() (float64, float64) {return 1, 2}
func f2(float64, float64) {}
func f3(float64, float64, float64) {}
func f4()(x, y []int) {return}
func f5()(x map[int]int, y int) {return}

type I interface {m()(float64, float64)}
type T struct{}
func (T) m()(float64, float64) {return 1, 2}

func main() {
	// These lines compile okay.
	f2(f0(), 123)
	f2(f1())
	fmt.Println(f1())
	_ = complex(f1())
	_ = complex(T{}.m())
	f2(I(T{}).m())

	// These lines don't compile.
	/*
	f3(123, f1())
	f3(f1(), 123)
	println(f1())
	// The following 3 lines compiles okay
	// only since Go SDK 1.13.
	copy(f4())
	delete(f5())
	_ = complex(I(T{}).m())
	*/
}
</code></pre>
</div>

<!--
<h3>Unused variables</h3>

<div>
The basic rule:
<div class="alert alert-info">
Local variables can't be declared but not used.
</div>

Exception:
<div class="alert alert-success">
Function parameter and result variables,
which can also be viewed as local variables,
are allowed to be not used.
</div>
</div>
-->

<h3>Select struct fields</h3>

<div>
The basic rule:
<div class="alert alert-info">
Pointer values have no fields.
</div>

Sugar:
<div class="alert alert-success">
We can select the fields of a struct value through pointers of the struct value.
</div>

Example:
<pre class="line-numbers"><code class="language-go">package main

type T struct {
	x int
}

func main() {
	var t T
	var p = &t

	p.x *= 2
	// The above line is a sugar of the following line.
	(*p).x *= 2
}
</code></pre>
</div>

<h3>Receiver arguments of method calls</h3>

<div>
The basic rule:
<div class="alert alert-info">
The methods explicitly declared for type <code>*T</code> are not methods of type <code>T</code> for sure.
</div>

Sugar:
<div class="alert alert-success">
Although the methods explicitly defined on type <code>*T</code> are not methods of type <code>T</code>,
addressable values of type <code>T</code> can be used as the receiver arguments of calls to these methods.
</div>

Example:
<pre class="line-numbers"><code class="language-go">package main

type T struct {
	x int
}

func (pt *T) Double() {
	pt.x *= 2
}

func main() {
	// T{3}.Double() // This line fails to compile.

	var t = T{3}

	t.Double() // t.x == 6 now
	// The above line is a sugar of the following line.
	(&t).Double() // t.x == 12 now
}
</code></pre>
</div>

<h3>Take addresses of composite literal values</h3>

<div>
The basic rule:
<div class="alert alert-info">
Literal values are unaddressable and unaddressable values can't be taken addresses.
</div>

Sugar:
<div class="alert alert-success">
Although composite literal values are not addressable, they can be taken addresses explicitly.
</div>

<p>
Please read <a href="struct.html#take-composite-literal-address">structs</a>
and <a href="container.html#take-composite-literal-address">containers</a> for details.
</p>
</div>

<h3>Selectors on defined one-Level pointers</h3>

<div>
The basic rule:
<div class="alert alert-info">
Generally, selectors can't be used on values of <a href="type-system-overview.html#underlying-type">defined</a> pointer types.
</div>

Sugar:
<div class="alert alert-info">
If <code>x</code> is a value of a defined one-level pointer type,
and selector <code>(*x).f</code> is a legal selector,
then the <code>x.f</code> is also a legal selector, it can be viewed as a shorthand of <code>(*x).f</code>.
</div>

<p>
Selectors can never be used on values of <b>multi-level</b> pointer types,
no matter whether the multi-level pointer types are defined or not.
</p>

Exception of the sugar:
<div class="alert alert-success">
The sugar is only valid if <code>f</code> denotes a struct field,
it is not valid if <code>f</code> denotes a method.
</div>

Example:
<pre class="line-numbers"><code class="language-go">package main

type T struct {
	x int
}

func (T) y() {
}

type P *T
type PP **T // a multi-level pointer type

func main() {
	var t T
	var p P = &t
	var pt = &t   // type of pt is *T
	var ppt = &pt // type of ppt is **T
	var pp PP = ppt
	_ = pp

	_ = (*p).x // legal
	_ = p.x    // also legal (for x is a field)

	_ = (*p).y // legal
	// _ = p.y // illegal (for y is a method)

	// Following ones are all illegal.
	/*
	_ = ppt.x
	_ = ppt.y
	_ = pp.x
	_ = pp.y
	*/
}
</code></pre>
</div>

<!--
<h3>Precedence of unary operators</h3>

<div>
The basic rule:
<div class="alert alert-info">
For any operand, its post operator has a higher precedence than its pre operator if the post operator
is not a <a href="https://golang.org/ref/spec#Operators">binary operator</a>.
</div>

Sugar:
<div class="alert alert-success">
Assume operand <code>ptr</code> is a pointer value, in <code>*ptr++</code>, operator <code>*</code> has
a higher precedence than operator <code>++</code>, a.k.a., <code>*ptr++</code> is equivalent to
<code>(*ptr)++</code>, for pointer arithmetic is not supported in Go.
</div>

Example:
<pre class="line-numbers"><code class="language-go">package main

import (
	"fmt"
)

type T struct{}

func (t T) M() *int {
	var v = 123
	return &v
}

func main() {
	var t = &T{}
	var a = *t.M()
	var b = *(t.M())
	// The above two lines are equivalent.
	var c = (*t).M()
	fmt.Printf("%T %T %T\n", a, b, c) // int int *int

	var s = [...]int{0, 1, 2}
	var u = &s[0]
	var v = &(s[0])
	// The above two lines are equivalent.
	var w = (&s)[0]
	fmt.Printf("%T %T %T\n", u, v, w) // *int *int int

	// sugar

	var x = new(int)
	*x++ // *x == 1 now
	// The Above line is a sugar for
	(*x)++
}
</code></pre>
</div>
-->

<h3>The addressability of a container and its elements</h3>

<div>
The basic rule:
<div class="alert alert-info">
If a container is addressable, then its elements are also addressable.
</div>

Exception:
<div class="alert alert-success">
Elements of a map are always unaddressable, even if the map itself is addressable.
</div>

Sugar:
<div class="alert alert-success">
Elements of a slice are always addressable, even if the slice itself is not addressable.
</div>

Example:
<pre class="line-numbers"><code class="language-go">package main

func main() {
	var m = map[string]int{"abc": 123}
	_ = &m // okay

	// The exception:
	// p = &m["abc"] // error: map elements are unaddesable

	// The sugar:
	f := func() []int { // return results are unaddressable
		return []int{0, 1, 2}
	}
	// _ = &f() // error: f() is unaddressable
	_ = &f()[2] // okay
}
</code></pre>
</div>

<h3>Modify unaddressable values</h3>

<div>
The basic rule:
<div class="alert alert-info">
Unaddressable values can't be modified.
In other words, unaddressable values shouldn't appear in assignments as destination values.
</div>

Exception:
<div class="alert alert-success">
Although map element values are unaddressable, they can be modified
and appear in assignments as destination values.
(But map elements can't be modified partially,
they can only be overwritten wholly, a.k.a., replaced.)
</div>

Example:
<pre class="line-numbers"><code class="language-go">package main

func main() {
	type T struct {
		x int
	}

	var mt = map[string]T{"abc": {123}}
	// Map elements are unaddressable.
	// _ = &mt["abc"] // error
	// Partial modification is not allowed.
	// mt["abc"].x = 456 // error
	// It is ok to replace a map element as a whole.
	mt["abc"] = T{x: 789}
}
</code></pre>
</div>

<h3>Function Parameters</h3>

<div>
The basic rule:
<div class="alert alert-info">
Each parameter is a value of some type.
</div>

Exception:
<div class="alert alert-success">
The first parameters of the built-in <code>make</code> and <code>new</code> functions are types.
</div>

</div>

<h3>Function names in one package</h3>

<div>
The basic rule:
<div class="alert alert-info">
Names of declared functions can't be duplicated in one package.
</div>

Exception:
<div class="alert alert-success">
There can be multiple functions declared with names as <code>init</code>
(with the prototype <code>func()</code>).
</div>

</div>

<h3>Function calls</h3>

<div>
The basic rule:
<div class="alert alert-info">
Functions whose names are not the blank identifier can be called in user code.
</div>

Exception:
<div class="alert alert-success">
<code>init</code> functions can't be called in user code.
</div>

</div>

<h3>Functions being used as values</h3>

<div>
The basic rule:
<div class="alert alert-info">
Declared functions can be used as function values.
</div>

Exception 1:
<div class="alert alert-success">
None of the built-in functions, which declared in the <code>builtin</code> and <code>unsafe</code>
standard packages, can be used as function values.
</div>

Exception 2:
<div class="alert alert-success">
<code>init</code> functions can not be used as function values.
</div>

Example:
<pre class="line-numbers"><code class="language-go">package main

import "fmt"
import "unsafe"

func init() {}

func main() {
	// These ones are okay.
	var _ = main
	var _ = fmt.Println

	// These ones fail to compile.
	var _ = panic
	var _ = unsafe.Sizeof
	var _ = init
}
</code></pre>
</div>


<a class="anchor" id="discard-return-results"></a>
<h3>Discard return values of function calls</h3>

<div>

The basic rule:
<div class="alert alert-info">
The return values of a function call can be discarded all together.
</div>

Exception:
<div class="alert alert-success">
The return values of calls to the built-in functions
which are declared in the <code>builtin</code> and <code>unsafe</code>
standard packages, can't be discarded, if the called function has return results.
</div>

Exception in exception:
<div class="alert alert-success">
The return values of a call to the built-in
<code>copy</code> and <code>recover</code> functions
can be all discarded, even if the two functions have return results.
</div>

</div>

<h3>Declared variables</h3>

<div>
The basic rule:
<div class="alert alert-info">
Declared variables are always addressable.
</div>

Exception:
<div class="alert alert-success">
The <a href="https://golang.org/pkg/builtin/#pkg-variables">predeclared <code>nil</code></a> variable is not addressable.
</div>

So, <code>nil</code> is an immutable variable.
</div>

<h3>Argument passing</h3>

<div>
The basic rule:
<div class="alert alert-info">
An argument can be passed to the corresponding function parameter
only if the argument is assignable to the corresponding function parameter type.
</div>

Sugar:
<div class="alert alert-success">
If the first slice argument of a <code>copy</code> and <code>append</code> function call
is a byte slice, then the second argument can be a string,
whereas a string value is not assignable to the second parameter type (also a byte slice).
(For an <code>append</code> call, assume the second argument is passed with the form <code>arg...</code>.)
</div>

Example:
<pre class="line-numbers"><code class="language-go">package main

func main() {
	var bs = []byte{1, 2, 3}
	var s = "xyz"

	copy(bs, s)
	// The above line is a sugar (and an optimization)
	// for the following line.
	copy(bs, []byte(s))

	bs = append(bs, s...)
	// The above line is a sugar (and an optimization)
	// for the following line.
	bs = append(bs, []byte(s)...)
}
</code></pre>
</div>

<h3>Comparisons</h3>

<div>
The basic rule:
<div class="alert alert-info">
Map, slice and function types don't support comparison.
</div>

Exception:
<div class="alert alert-success">
Map, slice and function values can be compared to the predeclared untyped <code>nil</code> identifier.
</div>

Example:
<pre class="line-numbers"><code class="language-go">package main

func main() {
	var s1 = []int{1, 2, 3}
	var s2 = []int{7, 8, 9}
	//_ = s1 == s2 // error: slice values can't be compared
	_ = s1 == nil // ok
	_ = s2 == nil // ok

	var m1 = map[string]int{}
	var m2 = m1
	// _ = m1 == m2 // error: map values can't be compared
	_ = m1 == nil
	_ = m2 == nil

	var f1 = func(){}
	var f2 = f1
	// _ = f1 == f2 // error: functions can't be compared
	_ = f1 == nil
	_ = f2 == nil
}
</code></pre>
</div>

<h3>Comparisons 2</h3>

<div>
The basic rule:
<div class="alert alert-info">
If a value is assignable to the type of another value, then the two values can be compared.
</div>

Exception:
<div class="alert alert-success">
The values of a non-interface incomparable type can't be compared to values of an interface type,
even if the non-interface incomparable type implements the interface type
(so values of the non-interface incomparable type are assignable to the interface type).
</div>

Please read <a href="value-conversions-assignments-and-comparisons.html#comparison-rules">comparison rules</a> for examples.
</div>

<!--
<h3>Comparing interface values</h3>

<div>
The basic rule:
<div class="alert alert-info">
Comparing interface values with incomparable dynamic values will panic.
</div>

Exception:
<div class="alert alert-success">
If the dynamic types of two interface values are not the same one,
then comparing them will never panic,
even if either of the two dynamic values are incomparable.
</div>

Example:
<pre class="line-numbers"><code class="language-go">package main

func main() {
	var s = []int{1, 2, 3}
	var m = map[string]int{}
	var x interface{} = s
	var y interface{} = m
	var z interface{} = nil
	// The dynamic values of x and y are both incomparable.
	//_ = x == x // will panic
	//_ = y == y // will panic
	_ = x == z // false, will not panic
	_ = x == y // false, will not panic
}
</code></pre>
</div>
-->

<h3>Blank composite literals</h3>

<div>
The basic rule:
<div class="alert alert-info">
If the values of a type <code>T</code> can be represented with composite literals, then <code>T{}</code> is its zero value.
</div>

Exception:
<div class="alert alert-success">
For a map or a slice type <code>T</code>, <code>T{}</code> isn't its zero value.
Its zero value is represented with <code>nil</code>.
</div>

Example:
<pre class="line-numbers"><code class="language-go">package main

import "fmt"

func main() {
	// new(T) returns the address of a zero value of type T.

	type T0 struct {
		x int
	}
	fmt.Println( T0{} == *new(T0) ) // true
	type T1 [5]int
	fmt.Println( T1{} == *new(T1) ) // true

	type T2 []int
	fmt.Println( T2{} == nil ) // false
	type T3 map[int]int
	fmt.Println( T3{} == nil ) // false
}
</code></pre>
</div>

<h3>Container element iterations</h3>

<div>
The basic rule:
<div class="alert alert-info">
Only container values can be ranged, the iterated values are container elements.
The element key/index will also be returned alongside of each iterated element.
</div>

Exception 1:
<div class="alert alert-success">
The iterated values are runes if the ranged containers are strings, instead of the byte elements of strings.
</div>

Exception 2:
<div class="alert alert-success">
The element index (order) will not be returned alongside of each iterated element when iterating channels.
</div>

Sugar:
<div class="alert alert-success">
Array pointers can also be ranged to iterate array elements, though pointers are not containers.
</div>

</div>

<h3>Methods of built-in types</h3>

<div>
The basic rule:
<div class="alert alert-info">
Generally, built-in types have no methods.
</div>

Exception:
<div class="alert alert-success">
The built-in <code>error</code> type has a <code>Error() string</code> method.
</div>
</div>

<!--
<h3>Identifier visibility</h3>

<div>
The basic rule:
<div class="alert alert-info">
The identifiers not starting with Unicode upper case letters can't be exported.
</div>

Exception:
<div class="alert alert-success">
Identifiers starting with Unicode lower case letter in the <code>builtin</code> package
can be exported.
</div>
</div>
-->

<h3>Types of values</h3>

<div>
The basic rule:
<div class="alert alert-info">
Each value has either a type or a default type.
</div>

Exception:
<div class="alert alert-success">
Untyped <code>nil</code> has neither a type nor a default type.
</div>

</div>

<h3>Constant values</h3>

<div>
The basic rule:
<div class="alert alert-info">
Constant values never change.
Constant can be assigned to variables.
</div>

Exception:
<div class="alert alert-success">
Predeclared <code>iota</code> is a built-in constant which is bound with <code>0</code>,
but its value is not constant. Its value will start from <code>0</code>
and increase one constant specification by constant specification in a constant declaration,
though the increments happen at compile time.
</div>

Exception 2:
<div class="alert alert-success">
<code>iota</code> can only be used within constant declarations.
It can't be assigned to variables in variable declarations.
</div>

</div>

<a class="anchor" id="behaviors-on-missing-optional-result"></a>
<h3>Behavior change caused by discarding the optional evaluation results of expressions</h3>

<div>
The basic rule:
<div class="alert alert-info">
Whether or not the optional evaluation result of an expression is present will not affect program behavior.
</div>

Exception:
<div class="alert alert-success">
Missing the optional result value in a type assertion will make current goroutine panic if the type assertion fails.
</div>

Example:
<pre class="line-numbers"><code class="language-go">package main

func main() {
	var ok bool

	var m = map[int]int{}
	_, ok = m[123] // will not panic
	_ = m[123]     // will not panic

	var c = make(chan int, 2)
	c <- 123
	close(c)
	_, ok = <-c // will not panic
	_ = <-c     // will not panic

	var v interface{} = "abc"
	_, ok = v.(int) // will not panic
	_ = v.(int)     // will panic!
}
</code></pre>

</div>

<!--
https://github.com/golang/go/issues/27451
-->

